--BrowseUI.lua
require 'fairygui.Window'

local tinsert    = table.insert
local sformat    = string.format
local mfloor     = math.floor
local smatch     = string.match
local tremove    = table.remove
local fexists    = stdfs.exists

local time       = _G.time
local copy_file  = stdfs.copy_file
local rfile      = stdfs.remove

local GST_AUTO    = 0              -- 自动
local GST_MANUAL  = 1              -- 手动
local GST_QUICK   = 2              -- 快捷
local GST_STORY   = 3              -- 剧情

BrowseUI = class(Window)
local prop = property(BrowseUI)
prop:accessor("store_types", {})   -- 存档类型
prop:accessor("world", nil)
prop:accessor("world_child", nil)
prop:accessor("treeView", nil)
prop:accessor("inputSearch", nil)
prop:accessor("mode", "local")
prop:accessor("childNode", nil)

function BrowseUI:__init()
    self:loadLayout("BrowseUI", "Main")

    g_event_mgr:addListener(self, "onDelWorld")
    g_event_mgr:addListener(self, "onDelArchive")
    self.store_types = {[GST_AUTO]="自动存档",[GST_MANUAL]="手动存档",[GST_QUICK]="快捷存档",[GST_STORY]="剧情存档"}
end

-- 初始化(仅执行一次)
function BrowseUI:initEvent()
    local this = self
    -- 树结构
    self.treeView = self:getChild("TreeView")
    -- 树渲染
    self.treeView.treeNodeRender = function(node, obj)
        if (node.isFolder) then
            if type(node.data) == "table" then
                obj.text = node.data.name
            else
                obj.text = node.data
            end
        elseif type(node.data) == "table" then
            -- 设置存档类型
            local cTypeTag = node.cell:GetController("typeTag")
            cTypeTag.selectedIndex = node.data.store_type
            -- 设置最近游戏
            if node.data.lastVisit then
                local cLastVisit = node.cell:GetController("lastVisit")
                cLastVisit.selectedIndex = 1
            end
            if node.data.version_id == g_world_mgr.client_version_id or g_world_mgr.client_version_id == 0  then
                node.cell:GetController("compat").selectedIndex = 0
            else
                node.cell:GetController("compat").selectedIndex = 1
            end
            -- 设置剧情类型
            local storyModeTag = node.cell:GetController("storyMode")
            storyModeTag.selectedIndex = node.data.story_mode
            -- 远程类型
            local remoteController = node.cell:GetController("remote")
            remoteController.selectedIndex = self:isRemote() and 1 or 0
            -- 设置存档名称
            node.cell:GetChild("subName").text = node.data.name
            -- 设置昵称
            node.cell:GetChild("roleName").text = node.data.masterNick
            -- 设置操作时间
            node.cell:GetChild("saveTime").text = time.tstostr(mfloor(node.data.operateTime/1000))
        else
            obj.text = node.data
        end
    end
    -- 树下拉刷新
    self.treeView.scrollPane.onPullDownRelease:Add(function()
        local header = self.treeView.scrollPane.header;
        if header:GetController("c1").selectedIndex == 1 then
            header:GetController("c1").selectedIndex = 2;
            self.treeView.scrollPane:LockHeader(header.sourceHeight);
            local callback = function(err)
                g_time_mgr:add(1, 1, function()
                if err then
                    g_event_mgr:notifyListener("onWarnTip", err)
                    header:GetController("c1").selectedIndex = 0;
                    self.treeView.scrollPane:LockHeader(0);
                    return
                end
                header:GetController("c1").selectedIndex = 3;
                self.treeView.scrollPane:LockHeader(35);
                g_time_mgr:add(2, 1, function()
                    header:GetController("c1").selectedIndex = 0;
                    self.treeView.scrollPane:LockHeader(0);
                end)
            end)
            end
            if self:isLocal() then
                self:initLocalUI(callback)
            else
                g_world_mgr:loadRemoteWorlds(function(err)
                    if err then
                        print("[BrowseUI][loadRemoteWorlds] err:"..err)
                        return
                    end
                    self:initRemoteUI(callback)
                end)
            end
        end
    end);
    self.treeView.scrollPane.header.onSizeChanged:Add(function()
        local selectedIndex = self.treeView.scrollPane.header:GetController("c1").selectedIndex;
        if selectedIndex == 2 or selectedIndex == 3 then
            return;
        end
        local c1 = self.treeView.scrollPane.header:GetController("c1");
        if self.treeView.scrollPane.header.height > self.treeView.scrollPane.header.sourceHeight then
            c1.selectedIndex = 1;
        else
            c1.selectedIndex = 0;
        end
    end);
    self.inputSearch = self:getChild("inputSearch")
    -- 搜索世界
    self.inputSearch.onChanged:Add(function()
        self:searchWorld()
    end)
    -- 列表响应
    self.treeView.onClickItem:Add(function(context)
        -- 获取树节点
        local node = context.data.treeNode
        -- 父节点
        if node.level == 1 then
            this:initParentUIData(node)
        -- 子节点
        elseif node.level == 2 then
            this:initChildUIData(node)
        end
    end);
    -- 返回
    local back = self:getChild("Back");
    back.onClick:Add(function()
        self.treeView:RemoveChildren()
        local ui = self:openGUI("StartUI", true)
        if ui and self:isRemote() then
            ui:openRemoteUI()
        end
        self:close()
    end)
    -- 打开存档
    self:addClick("Open", function()
        if not self.world_child then
            print("[BrowseUI][initEvent] Open world_child")
            return
        end
        self:openDbFile(self.world_child.path_utf8, self.world_child.dbname)
    end)
    -- 下载存档
    self:getChild("Down").onClick:Add(function()
        self:downLoadDbFile(self.world_child.dbname)
    end)
    -- 刷新存档
    self:getChild("Refresh").onClick:Add(function()
        self:downLoadDbFile(self.world_child.dbname)
    end)
    -- 导出存档
    self:getChild("Export").onClick:Add(function()
        if not self.world_child then
            print("[BrowseUI][initEvent] Export world_child")
            return
        end
        local selectedPath = CS.NativeFolderDialog.SaveAsFile(self.world_child.name, ".db")
        if selectedPath then
            local path = self.world_child.path
            local ok,err = copy_file(path, selectedPath)
            if not ok then
                g_event_mgr:notifyListener("onWarnTip", "导出失败")
                print(sformat("[BrowseUI][initEvent] SaveAsFile source:%s target:%s err:%s", path, selectedPath, err))
                return
            end
            g_event_mgr:notifyListener("onSuccessTip", "导出成功")
        end
    end)
    -- 拷贝
    self:getChild("Copy").onClick:Add(function()
        if not self.world_child then
            print("[BrowseUI][initEvent] Copy world_child")
            return
        end
        if not g_world_mgr:copyWorld(self.world_child) then
            g_event_mgr:notifyListener("onWarnTip", "拷贝失败")
            return
        end
        g_event_mgr:notifyListener("onSuccessTip", "拷贝成功")
    end)
    -- 删除世界
    self:getChild("DelWorld").onClick:Add(function()
        if not self.world then
            print("[BrowseUI][initEvent] DelWorld world")
            return
        end
        local panel = self:openGUI("DelteWorldUI")
        panel:SetInfo(self.world.id, self.world.world_name)
    end)
    -- 删除存档
    self:getChild("DelArchive").onClick:Add(function()
        if not self.world then
            print("[BrowseUI][initEvent] DelArchive world")
            return
        end
        local panel = self:openGUI("DelteArchiveUI")
        panel:SetInfo(self.world_child.id, self.world_child.store_name)
    end)
    -- 修改版本号
    self:getChild("ChildGameVer").onClick:Add(function()
        if self:isRemote() then
            g_event_mgr:notifyListener("onWarnTip", "远程存档不支持修改!")
            return
        end
        self:switchVerEdit("edit")
        local childInputVer = self:getChild("ChildInputVer")
        self:InputRequestFocus(childInputVer)
    end)
    -- 保存版本号
    self:getChild("SaveVer").onClick:Add(function()
        local panel = self:openGUI("Message")
        panel:Show("提示", "请确保游戏已停止运行（在编辑器中点击停止）或已完全关闭（打包运行的游戏）。", function(result)
            if(not result) then
                g_event_mgr:notifyListener("onWarnTip", "操作取消")
                return
            end
            local childInputVer = self:getChild("ChildInputVer")
            local version_id = tonumber(childInputVer.text)
            self:saveGameVersion(version_id, function(err)
                if err then
                    g_event_mgr:notifyListener("onWarnTip", err)
                    print("[BrowseUI][initEvent] saveGameVersion err:"..err)
                    return
                end
                self:switchVerEdit("default")
                g_event_mgr:notifyListener("onSuccessTip", "操作成功,请重新启动游戏查看")
            end)
        end)
    end)
    -- 兼容游戏版本
    self:getChild("CompatVer").onClick:Add(function()
        local panel = self:openGUI("Message")
        panel:Show("提示", "请确保游戏已停止运行（在编辑器中点击停止）或已完全关闭（打包运行的游戏）。", function(result)
            if(not result) then
                g_event_mgr:notifyListener("onWarnTip", "操作取消")
                return
            end
            local version_id = g_world_mgr.client_version_id
            if version_id == 0 then
                g_event_mgr:notifyListener("onWarnTip", "操作失败,无法获取游戏客户端版本,请联系开发人员协助!")
                return
            end
            self:saveGameVersion(version_id, function(err)
                if err then
                    g_event_mgr:notifyListener("onWarnTip", err)
                    print("[BrowseUI][initEvent] saveGameVersion err:"..err)
                    return
                end
                g_event_mgr:notifyListener("onSuccessTip", "操作成功,请重新启动游戏查看!")
            end)
        end)
    end)
    -- 打开存档文件路径
    self:addClick("ChildDbName",function()
        if self.world_child.path == "" then
            print("[BrowseUI][initEvent] OpenPath world")
            return
        end
        if not fexists(self.world_child.path) then
            print("[BrowseUI][initEvent] OpenPath file err path:"..self.world_child.path)
            return
        end
        local cmd = 'explorer /select,"' .. self.world_child.path:gsub("/", "\\") .. '"'
        io.popen(cmd, 'r')
    end)
    -- 查看账号索引文件
    self:addClick("Account",function()
        self:downLoadDbFile(g_world_mgr.open_id, function(err)
            if err then
                print("[BrowseUI][initEvent] Account downLoadDbFile err open_id:"..g_world_mgr.open_id)
                return
            end
            self:openDbFile(g_world_mgr.user_db_file, g_world_mgr.open_id)
        end)
    end)
    -- 切换用户
    self:addClick("SwitchUser",function()
        self:openGUI("RemoteUI")
    end)
    -- 远程日志
    self:addClick("RemoteLog",function()
        self:openGUI("RemoteLogUI")
    end)
    -- 缓存目录
    self:addClick("Folder",function()
        local cmd = 'explorer /n,"' ..g_world_mgr.user_cache_path..'"'
        cmd = cmd:gsub("/", "\\")
        io.popen(cmd, 'r')
    end)
    -- 清理缓存
    self:addClick("Clear",function()
        local ok = rfile(g_world_mgr.user_cache_path, true)
        if not ok then
            g_event_mgr:notifyListener("onWarnTip", "清理失败,请检查文件是否被占用!")
            print("[BrowseUI][initEvent] Clear fail path:"..g_world_mgr.user_cache_path)
            return
        end
        g_world_mgr:initUserDir()
        self:getController("fexists").selectedIndex = 1
        g_event_mgr:notifyListener("onSuccessTip", "清理成功")
    end)
end

-- 打开UI执行一次
function BrowseUI:initComponent()
    self:switchVerEdit("default")
end

-- 打开存档
function BrowseUI:openDbFile(path, dbname)
    _G.JumpFile = path
    _G.BackUI = "BrowseUI"
    self:close()
    local panel = self:openGUI("MainUI", true)
    panel:initData({
        db_name = dbname,
        is_remote = self:isRemote()
    })
end

-- 下载存档文件
function BrowseUI:downLoadDbFile(dbname, callback)
    if self:isRemote() then
        g_world_mgr:downRemoteDbFile(dbname, function(err, data)
            if err then
                if callback then
                   callback(err)
                end
                g_event_mgr:notifyListener("onWarnTip", err)
                print("[BrowseUI][initEvent] downRemoteDbFile fail dbname:"..dbname)
                return
            end
            -- 切换控制器
            local control = self:getController("fexists")
            local childDbName = self:getChild("ChildDbName")
            childDbName:SetVar("name", dbname)
            childDbName:FlushVars()
            control.selectedIndex = 0
            g_event_mgr:notifyListener("onSuccessTip", "下载成功")
            if callback then
                callback()
            end
        end)
    end
end

function BrowseUI:setMode(name)
    self.mode = name
    local control = self:getController("mode")
    control:SetSelectedPage(name)
end

function BrowseUI:initLocalUI(callback)
    print("[BrowseUI][initLocalUI]")
    self:setMode("local")
    g_world_mgr:loadData()
    self:getChild("GameVersion").text = g_world_mgr.client_version
    if #g_world_mgr.world_list == 0 then
        self:switchInfoPage("null")
    end
    self:initTreeData()
    self:getChild("txtNumInfo").text = #g_world_mgr.world_list
     if callback then
        callback()
    end
end

function BrowseUI:initRemoteUI(callback)
    self:setMode("remote")
    local remoteTitle = self:getChild("remoteTitle")
    remoteTitle:SetVar("name", g_world_mgr.user)
    remoteTitle:FlushVars()

    local userInfo = self:getChild("userInfo")
    userInfo:SetVar("open_id", g_world_mgr.open_id)
    userInfo:SetVar("user", g_world_mgr.user)
    userInfo:SetVar("host", g_world_mgr.host)
    userInfo:FlushVars()

    if #g_world_mgr.world_list == 0 then
        self:switchInfoPage("null")
    end
    self:initTreeData()
    if callback then
        callback()
    end
end

-- 本地模式
function BrowseUI:isLocal()
    return self.mode == "local"
end

-- 远程模式
function BrowseUI:isRemote()
    return self.mode == "remote"
end

-- 更新版本号UI
function BrowseUI:upGameVersionUI()
    local childGameVer = self:getChild("ChildGameVer")
    childGameVer:SetVar("name", self.world_child.store_version_id)
    childGameVer:FlushVars()
    self:SetChildText("ChildInputVer", self.world_child.store_version_id)
    local compatVerIndex = 0
    if g_world_mgr.client_version_id ~= 0 and self.childNode.data.version_id ~= g_world_mgr.client_version_id then
        compatVerIndex = 1
        if self.childNode.data.version_id < g_world_mgr.client_version_id then
            self:getChild("CompatTip").text = "版本较旧，可能不兼容!"
        else
            self:getChild("CompatTip").text = "版本较新，可能不兼容!"
        end
        self.childNode.cell:GetController("compat").selectedIndex = 1
    else
        self.childNode.cell:GetController("compat").selectedIndex = 0
    end
    self:getController("compatVer").selectedIndex = compatVerIndex
end

-- 保存版本号
function BrowseUI:saveGameVersion(version_id, callback)
    if self:isLocal() then
        local path = self.world_child.path
        if not g_store_mgr:load(path) then
            print("[BrowseUI][saveGameVersion] load file failed:", path)
            callback("load err")
            return
        end
        local store = g_store_mgr:getCurStore()
        if not store then
            print("[BrowseUI][saveGameVersion] store file failed:", path)
            callback("store err")
            return
        end
        local sheet = "world_storage"
        local sheetKey = tostring(self.world_child.world_id)
        local value = store:get(sheet, sheetKey)
        value.store_version_id = version_id
        store:put(sheetKey, value, sheet)
        local name = stdfs.filename(path)
        g_store_mgr:close(name)
        local upCount = g_world_mgr:upAccountGameVersion(self.world_child, version_id);
        if(upCount == 0) then
            g_event_mgr:notifyListener("onWarnTip", "操作可能失败,请联系开发人员协助!")
        end
        -- 更新ui数据
        self.childNode.data.version_id = version_id
        self.world_child.store_version_id = version_id
        self:upGameVersionUI()
        callback(nil, version_id)
        return
    end
    -- 远程存档
    g_world_mgr:saveRemoteVersion(self.world_child.dbname, self.world_child.world_id, version_id, function(err)
        if err then
            print("[BrowseUI[saveGameVersion] saveRemoteVersion fail err:"..err)
            callback(err)
            return
        end
        callback(nil, version_id)
        g_event_mgr:notifyListener("onSuccessTip", "保存成功")
    end)
end

function BrowseUI:searchWorld()
    local searchText = self.inputSearch.text:gsub(" ", "")
    if searchText == "" then
        self.treeView:CollapseAll()
        local defaultNode = nil
        for i, world in ipairs(g_world_mgr.world_list) do
            world.node.cell.visible = true
            for j, child in ipairs(world.childs) do
                if child.node.cell then
                    child.node.cell.visible = true
                end
                if i==1 and j == 1 then
                    defaultNode = child.node
                end
            end
        end
        if defaultNode then
            self.treeView:SelectNode(defaultNode)
            self:initChildUIData(defaultNode)
        end
        return
    end
    self.treeView:ExpandAll()
    searchText = searchText:lower()
    for _, world in ipairs(g_world_mgr.world_list) do
        local mathCount = 0
        for _, child in ipairs(world.childs) do
            local store_sub_name = child.store_sub_name:lower()
            local dbname = child.name:lower()
            if child.store_type == GST_MANUAL and smatch(store_sub_name, searchText) then
                mathCount = mathCount + 1
                if child.node.cell then
                    child.node.cell.visible = true
                end
                goto continue
            end
            if smatch("快捷存档", searchText) and child.store_type == GST_QUICK then
                mathCount = mathCount + 1
                if child.node.cell then
                    child.node.cell.visible = true
                end
                goto continue
            end
            if smatch("手动存档", searchText) and child.store_type == GST_MANUAL then
                mathCount = mathCount + 1
                if child.node.cell then
                    child.node.cell.visible = true
                end
                goto continue
            end
            if smatch("自动存档", searchText) and child.store_type == GST_AUTO then
                mathCount = mathCount + 1
                if child.node.cell then
                    child.node.cell.visible = true
                end
                goto continue
            end
            if smatch("剧情存档", searchText) and child.store_type == GST_STORY then
                mathCount = mathCount + 1
                if child.node.cell then
                    child.node.cell.visible = true
                end
                goto continue
            end
            if smatch(dbname, searchText) then
                mathCount = mathCount + 1
                if child.node.cell then
                    child.node.cell.visible = true
                end
                goto continue
            end
            if child.node.cell then
                child.node.cell.visible = false
            end
            :: continue ::
        end
        if world.node.cell then
            world.node.cell.visible = mathCount > 0 and true or false
            if world.node.cell.visible then
                self.treeView:ExpandAll(world.node)
            end
        end
    end
end

function BrowseUI:delWorld(world_id)
    for i,world in ipairs(g_world_mgr.world_list) do
        if world.id == world_id then
            tremove(g_world_mgr.world_list, i)
        end
    end
    -- 初始化世界信息
    self:getChild("txtNumInfo").text = #g_world_mgr.world_list
end

function BrowseUI:delChild(child_id)
    local child = g_world_mgr.world_childs[child_id]
    if not child then
        print("[BrowseUI][delChild] child child_id:"..child_id)
        return
    end
    local world_id = child.world_id
    local world = g_world_mgr.world_map[world_id]
    if world then
        for i=#world.childs, 1, -1 do
            if world.childs[i].id == child_id then
                tremove(world.childs, i)
            end
        end
        if #world.childs == 0 then
            g_world_mgr.world_map[world_id] = nil
            for i=#g_world_mgr.world_list, 1, -1 do
                local item = g_world_mgr.world_list[i]
                if item.id == world_id then
                    g_world_mgr.world_list[i] = nil
                    tremove(g_world_mgr.world_list, i)
                    break
                end
            end
        end
    end
    g_world_mgr.world_childs[child_id] = nil
    -- 初始化世界信息
    self:getChild("txtNumInfo").text = #g_world_mgr.world_list
    if #g_world_mgr.world_list == 0 then
        self:switchInfoPage("null")
    end
    return world
end

-- 初始化树UI数据
function BrowseUI:initTreeData()
    self.treeView:RemoveChildren()
    local defaultNode = nil
    for i, world in ipairs(g_world_mgr.world_list) do
        local parentNode = GTreeNode(true, "ui://0o1dt81pggmvydv")
        parentNode.data = {
            id = world.id,
            name = world.world_name,
        };
        self.treeView.rootNode:AddChild(parentNode)
        world.node = parentNode
        -- 最后游玩
        local cLastVisit = parentNode.cell:GetController("lastVisit")
        cLastVisit.selectedIndex = (i == 1 and 1 or 0)
        for j, child in ipairs(world.childs) do
            local childNode = GTreeNode(false, "ui://0o1dt81pggmvydl")
            local store_name = child.store_sub_name
            if child.store_type == GST_AUTO then
                store_name = "自动存档"
            elseif child.store_type == GST_QUICK then
                store_name = "快捷存档"
            elseif child.store_type == GST_STORY then
                store_name = "剧情存档"
            end
            child.node = childNode
            child.parent_node = parentNode
            childNode.data = {
                name = store_name,
                world_id = child.world_id,
                masterNick = world.master_nick,
                child_id = child.id,
                store_type = child.store_type,
                story_mode = child.story_mode,
                lastVisit = (i==1 and j==1),
                operateTime = child.store_operate_time,
                saveTime = world.save_time,
                version_id = child.store_version_id
            }
            parentNode:AddChild(childNode)
            if i==1 and j == 1 then
                defaultNode = childNode
            end
        end
    end
    if defaultNode then
        self.treeView:SelectNode(defaultNode)
        self:initChildUIData(defaultNode)
    end
end

function BrowseUI:switchInfoPage(name)
    local controller = self:getController("treeInfo")
    controller:SetSelectedPage(name)
end

function BrowseUI:switchVerEdit(name)
    local controller = self:getController("editVer")
    controller:SetSelectedPage(name)
end

-- 设置节点text
function BrowseUI:SetChildText(name, val)
    local child = self:getChild(name)
    if not child then
        print("[BrowseUI][SetChildText] child name:", name)
        return
    end
    child.text = val
end

-- 初始化子节点数据
function BrowseUI:initChildUIData(node)
    self:switchInfoPage("child")
    local child_id = node.data.child_id
    self.childNode = node
    self.world_child = g_world_mgr.world_childs[child_id]
    if not self.world_child then
        print("[BrowseUI][initChildUIData] child child_id:", child_id)
        return
    end
    local world_id = self.world_child.world_id
    self.world = g_world_mgr.world_map[world_id]
    if not self.world then
        print("[BrowseUI][initChildUIData] world world_id:", self.world_child.world_id)
        return
    end
    self:upGameVersionUI()
    self:switchVerEdit("default")
    self:SetChildText("ChildGameTime", time.gamesec_tostr(self.world.world_time))
    self:SetChildText("ChildGameDuration", time.sectostr(mfloor(self.world.game_duration/1000)))
    self:SetChildText("ChildCreateTime", time.tstostr(mfloor(node.data.operateTime/1000)))
    self:SetChildText("ChildStoreType", self.store_types[self.world_child.store_type] or "未知类型")
    local childDbName = self:getChild("ChildDbName")
    local child = self:getChild("Thumb")
    local texture = CS.UnityEngine.Texture2D(2, 2);
    if self:isLocal() then
        self:getController("fexists").selectedIndex = 0
        local compatVerIndex = 0
        if g_world_mgr.client_version_id ~= 0 and node.data.version_id ~= g_world_mgr.client_version_id then
            compatVerIndex = 1
            if node.data.version_id < g_world_mgr.client_version_id then
                self:getChild("CompatTip").text = "版本较旧，可能不兼容!"
            else
                self:getChild("CompatTip").text = "版本较新，可能不兼容!"
            end
        end
        self:getController("compatVer").selectedIndex = compatVerIndex
        childDbName:SetVar("name", self.world_child.name)
        childDbName:FlushVars()
        CS.UnityEngine.ImageConversion.LoadImage(texture, self.world_child.store_thumb);
        child.texture = NTexture(texture)
    else
        g_world_mgr:queryRemoteThmb(self.world_child.storage_id, child_id, function(err, data)
            if err then
                print("[BrowseUI][initChildUIData] err:"..err)
                return
            end
            CS.UnityEngine.ImageConversion.LoadImage(texture, data.thumb);
            child.texture = NTexture(texture)
        end)
        print("path:"..self.world_child.path)
        -- 验证存档文件是否存在
        if fexists(self.world_child.path) then
            self:getController("fexists").selectedIndex = 0
            childDbName:SetVar("name", self.world_child.name)
            childDbName:FlushVars()
        else
            self:getController("fexists").selectedIndex = 1
        end
    end
end

-- 初始化父节点数据
function BrowseUI:initParentUIData(node)
    self:switchInfoPage("parent")
    self.world = g_world_mgr.world_map[node.data.id]
    if not self.world then
        print("[BrowseUI][initParentUIData] world world_id:", self.world_child.world_id)
        return
    end
    local child = self.world.childs[1]
    if not child then
        print("[BrowseUI][initParentUIData] child world_id:", self.world_child.world_id)
        return
    end
    self:SetChildText("ParentWorldLevel", self.world.world_lvl)
    self:SetChildText("ParentManualNum", self.world.types[GST_MANUAL] or 0)
    self:SetChildText("ParentGameCount", time.sectostr(mfloor(self.world.game_duration/1000)))
    self:SetChildText("ParentCreateTime", time.tstostr(mfloor(self.world.create_time)))
end

-- 删除世界
function BrowseUI:onDelWorld(world_id)
    local world = g_world_mgr.world_map[world_id]
    if not world then
        print("[BrowseUI][onDelWorld] world_id:"..world_id)
        return
    end
    local del_childs = {}
    for i=#world.childs, 1, -1 do
        local child = world.childs[i]
        local path = child.path
        local ok = rfile(path)
        if not ok then
            print("[BrowseUI][onDelWorld] rfile fail path:"..path)
            goto continue
        end
        tinsert(del_childs, child.id)
        world.node:RemoveChild(child.node)
        :: continue ::
    end
    for _,child_id in pairs(del_childs) do
        self:delChild(child_id)
    end
    for i,item_world in ipairs(g_world_mgr.world_list) do
        if item_world.id == world_id then
            g_world_mgr.world_list[i] = nil
        end
    end
    self.treeView.rootNode:RemoveChild(world.node)
    g_world_mgr.world_map[world_id] = nil
    self:delWorld(world_id)
end

-- 删除存档
function BrowseUI:onDelArchive(child_id)
    local child = g_world_mgr.world_childs[child_id]
    if not child then
        return
    end
    local path = child.path
    local ok = rfile(path)
    print("[BrowseUI][onDelArchive] path:"..path)
    if not ok then
        print("[BrowseUI][onDelArchive] rfile fail path:"..path)
    end
    child.parent_node:RemoveChild(child.node)
    local world = self:delChild(child.id)
    local world_id = child.world_id
    if not g_world_mgr.world_map[world_id] and world then
        self.treeView.rootNode:RemoveChild(world.node)
    end
end

function BrowseUI:onClose()
end